<template>
  <div class="about">
    <van-nav-bar
      :title="userInfo.radio === '01' ? '在线客服' : username"
      left-text="返回"
      left-arrow
      @click-left="onClickLeft"
    />
    <div class="messageBox">
      <div class="message" ref="scrollDiv">
        <div class="enterBox">
          <div
            class="enterBoxItem"
            v-for="(item, index) in enterList"
            :key="index"
          >
            {{
              item.type === "typeLeave"
                ? item.radio === "02"
                  ? "客服离开了在线咨询"
                  : `${item.username}离开了`
                : item.radio === "02"
                ? "客服进入了在线咨询"
                : `${item.username}进入了在线咨询`
            }}
          </div>
        </div>
        <div class="msgBox">
          <div
            class="msgContent"
            v-for="(item, index) in messageList"
            :key="`${item.username}${index}`"
            :class="item.username === userInfo.username ? 'right' : 'left'"
          >
            <div>
              <van-image width="50" height="50" :src="item.img" />
            </div>
            <div class="text" v-if="item.type === 'typeMessage'">
              {{ item.message }}
            </div>
            <div v-else><img class="image" :src="item.message" /></div>
          </div>
        </div>
      </div>
      <div class="opreation" :class="isOpen ? 'open' : ''">
        <div class="opreation-click">
          <div>
            <van-field
              v-model="message"
              rows="1"
              autosize
              type="textarea"
              placeholder="请输入消息"
              @keyup.enter="keyUpFn"
              @keydown.enter="handlePushKeyWord($event)"
            />
          </div>
          <div>
            <van-button
              @click="openUploadImg(false)"
              round
              icon="smile-o"
              size="small"
              type="default"
            />
          </div>
          <div>
            <van-button
              round
              icon="plus"
              size="small"
              type="default"
              @click="openUploadImg(true)"
            />
          </div>
        </div>
        <div class="upload" v-show="isOpen">
          <template v-if="flat">
            <van-uploader :after-read="afterRead" />
          </template>

          <template v-if="flat == false">
            <ul class="emojibox">
              <li
                @click="bqfs(item)"
                class="emojiList"
                v-for="(item, index) in emoji"
                :key="index"
              >
                {{ item.text }}
              </li>
            </ul>
          </template>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
const emojis = [
  "😀",
  "😄",
  "😅",
  "🤣",
  "😂",
  "😉",
  "😊",
  "😍",
  "😘",
  "😜",
  "😝",
  "😏",
  "😒",
  "🙄",
  "😔",
  "😴",
  "😷",
  "🤮",
  "🥵",
  "😎",
  "😮",
  "😰",
  "😭",
  "😱",
  "😩",
  "😡",
  "💀",
  "👽",
  "🤓",
  "🥳",
  "😺",
  "😹",
  "😻",
  "🤚",
  "💩",
  "👍",
  "👎",
  "👏",
  "🙏",
  "💪",
];

export default {
  data() {
    return {
      message: "",
      custumerName: "暂无买家",
      websock: null,
      enterList: [],
      messageList: [],
      isOpen: false,
      flat: true,
      is: "",
    };
  },
  computed: {
    userInfo() {
      return JSON.parse(localStorage.getItem("userInfos"));
    },
    emoji() {
      return emojis.map((e) => {
        return { text: e };
      });
    },
  },
  mounted() {},

  created() {
    this.initWebSocket();
  },
  beforeDestroy() {},
  methods: {
    // 上传图片
    bqfs(v) {
      this.message += v.text;
    },
    afterRead(files) {
      console.log(files.file);
      let { file } = files;
      let fr = new FileReader();
      fr.readAsDataURL(file);
      fr.onload = () => {
        let actions = {
          ...this.userInfo,
          message: fr.result,
          type: "typeImage",
        };
        this.websocketsend(JSON.stringify(actions));
        this.isOpen = false;
      };
    },
    // 打开图片上传的一个框
    openUploadImg(type) {
      // true 消息
      if (type) {
        this.flat = true;
      } else {
        this.flat = false;
      }

      this.isOpen = !this.isOpen;
    },
    // 禁止回车换行默认事件
    handlePushKeyWord(event) {
      let { keyCode } = event;
      if (keyCode === 13) {
        event.preventDefault();
        return false;
      }
    },
    // 通过回车键进行聊天内容的发送
    keyUpFn(e) {
      let actions = {
        ...this.userInfo,
        message: this.message,
        type: "typeMessage",
      };
      this.message && this.websock.send(JSON.stringify(actions));
      this.message = "";
    },
    onClickLeft() {
      this.$router.go(-1);
    },
    initWebSocket() {
      //初始化weosocket
      const wsuri = "ws://1.15.41.241:3000";
      this.websock = new WebSocket(wsuri);
      this.websock.onmessage = this.websocketonmessage;
      this.websock.onopen = this.websocketonopen;
      this.websock.onerror = this.websocketonerror;
      this.websock.onclose = this.websocketclose;
    },
    websocketonopen() {
      //连接建立之后执行send方法发送数据
      let actions = { ...this.userInfo, type: "typeEnter" };
      this.websocketsend(JSON.stringify(actions));
    },
    websocketonerror() {
      //连接建立失败重连
      this.initWebSocket();
    },
    websocketonmessage(e) {
      //数据接收
      let typeArray = ["typeMessage", "typeImage"];
      let redata = JSON.parse(e.data);
      let { type, radio, username, headerImage, message = "" } = redata;
      if (type === "typeEnter") {
        radio === "01" && (this.custumerName = `买家${username}`);
        console.log(redata);
        this.enterList.push(redata);
      } else if (typeArray.includes(type)) {
        this.messageList.push(redata);
      } else if (type === "typeLeave") {
        radio === "01" && (this.custumerName = "暂无买家");
        this.enterList.push(redata);
      }
      this.handleScrollBottom();
    },
    // 滚动到底部
    handleScrollBottom() {
      // console.log(this.$refs.scrollDiv);
      let scrollElem = this.$refs.scrollDiv;
      // 因为修改data里数据造成页面重新渲染后执行的函数
      // 如果不用$nextTick这个包裹scrollTo的话，就会拿不到最后需要滚动的举例
      if (!scrollElem && scrollElem.scrollTo) return;
      this.$nextTick(() => {
        scrollElem.scrollTo({
          top: scrollElem.scrollHeight,
          behavior: "smooth",
        });
      });
    },
    websocketclose(e) {
      //关闭
      console.log("断开连接", e);
    },
    // 给后端发送消息
    websocketsend(Data) {
      //数据发送
      this.websock.send(Data);
    },
  },
};
</script>
<style lang="less" scoped>
.emojibox {
  display: flex;
  flex-wrap: wrap;
  li {
    margin: 5px;
    width: 10px;
    text-align: center;
  }
}
.about {
  overflow: hidden;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  .messageBox {
    height: calc(100% - 46px);
    position: relative;
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: center;
    .message {
      flex: 1;
      width: 100%;
      overflow: auto;
      margin-bottom: 60px;
      .enterBox {
        .enterBoxItem {
          width: 100vw;
          color: darkgrey;
          font-size: 12px;
          text-align: center;
          height: 20px;
          line-height: 20px;
        }
      }
      .msgBox {
        .msgContent {
          display: flex;
          align-items: center;
          padding: 0 10px;
          word-break: break-all;
          .image {
            width: 100%;
          }
        }
        .right {
          flex-direction: row-reverse;
          .text {
            background: paleturquoise;
            padding: 4px 10px;
            border-radius: 5px;
            margin-right: 10px;
          }
        }
        .left {
          flex-direction: row;
          .text {
            background: palegoldenrod;
            padding: 4px 10px;
            border-radius: 5px;
            margin-left: 10px;
          }
        }
      }
    }
    .opreation {
      position: absolute;
      bottom: 0;
      width: 100%;
      min-height: 60px;
      background-color: gainsboro;
      transition: min-height 0.35s;
      &.open {
        min-height: 200px;
      }
      .opreation-click {
        width: 100%;
        height: 60px;
        display: grid;
        grid-template-columns: auto 50px 40px;
        text-align: center;
        box-sizing: border-box;
        padding: 10px 0 10px 10px;
        justify-items: center;
        align-items: center;
        justify-items: stretch;
      }
      .upload {
        padding-left: 10px;
      }
      .van-cell {
        padding: 8px 16px;
      }
    }
  }
}
</style>

